package flyweight;

import java.util.HashMap;

/**
 * 参考: 菜鸟教程-设计模式: https://www.runoob.com/design-pattern/flyweight-pattern.html
 *
 * 问题 1: 官方定义是什么? 自己理解又是什么?
     * 官方定义:
     * 享元模式（Flyweight Pattern）主要用于减少创建对象的数量，以减少内存占用和提高性能。
     *
     * 自己理解: 有些对象需要各个地方重复使用时, 用享元模式就能减少对象产生;
     * 类似于共享单车, 共享单车出现后, 大家买单车的数量就相对的少了;
 *
 * 问题 2: 为了解决什么问题
     * 解决相同对象被重复创建, 效率降低的问题
 *
 * 问题 3: 优缺点是什么
     * 优: 减少内存占用, 提高使用效率;
     * 缺: 往往会增加程序复杂度;
 *
 * 问题 4: 有什么典型的应用例子
     *  Java String 的常量池;
 */

public class FlyweightPattern {

//    private static final String colors[] = {"Red", "Green", "Blue", "White", "Black"};
    private static final String colors[] = {"Red", "Green"};

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor());
            circle.setX(getRandomX());
            circle.setY(getRandomY());
            circle.setRadius(100);
            circle.draw();
        }
    }

    private static String getRandomColor() {
        return colors[(int)(Math.random()*colors.length)];
    }
    private static int getRandomX() {
        return (int)(Math.random()*100 );
    }
    private static int getRandomY() {
        return (int)(Math.random()*100);
    }

}

interface Shape {
    void draw();
}

class Circle implements Shape {
    private String color;
    private int x;
    private int y;
    private int radius;

    public Circle(String color) {
        this.color = color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

    @Override
    public void draw() {
        System.out.println("Circle Draw() [Color : " + color + ", x : " + x + ", y : " + y + ", radius :" + radius);
    }
}

class ShapeFactory {
    private static final HashMap<String, Shape> circleMap = new HashMap<>();

    public static Shape getCircle(String color) {
        Circle circle = (Circle)circleMap.get(color);

        if (null == circle) {
            circle = new Circle(color);
            circleMap.put(color, circle);
            System.out.println("Ctreating circle of color : " + color);
        }
        return circle;
    }
}